// 引入软件串口库（用于连接espSerial）
#include <SoftwareSerial.h>

// 定义软件串口引脚（根据实际接线修改）
// 软件串口RX（接espSerial的TX）
#define ESP_RX 2
// 软件串口TX（接espSerial的RX）
#define ESP_TX 3

// 创建软件串口对象（用于与espSerial通信）
SoftwareSerial espSerial(ESP_RX, ESP_TX);

const String SSID = "ChinaNet-6x8c";
const String PASSWORD = "8zeymm8c";

bool isConnected=false;
String espIP="";
bool isStarted=false;
bool isModeSetted=false;
bool isMult=false;
bool isATOK=false;

int clientID = -1; 

void setup() {
  // 硬件串口（与电脑通信），波特率115200
  Serial.begin(115200);
  // 软件串口（与espSerial通信），波特率115200（需与模块匹配）
  espSerial.begin(115200);
  sendATCommand("AT+CIPMUX=1", 3000);
  sendATCommand("AT+CIFSR", 2000);
  sendATCommand("AT+CIPSERVER=1,8080", 2000);
}



void loop() {

    // 检查ESP8266返回信息（客户端连接/断开）
  if (espSerial.available()) {
    String response = espSerial.readStringUntil('\n');
    response.trim();

    Serial.println("ESP8266返回："+response);


    // 检测客户端连接
    if (response.indexOf("CONNECT") > 0) {
      clientID = response.charAt(0) - '0';  // 提取客户端ID
      Serial.println("客户端" + String(clientID) + "已连接");
    }

    // 检测客户端断开
    if (response.indexOf("CLOSED") > 0) {
      Serial.println("客户端已断开");
      clientID = -1;
    }

    //+IPD,0,1:F
    response=response.charAt(9);
    Serial.println("ESP8266提取后："+response);
    processCommand(response);

  }
}

/**
 * 向TCP客户端发送数据
 * @param clientID 客户端ID（0-4）
 * @param message 要发送的消息内容
 * @return 发送成功返回true，失败返回false
 */
bool sendToTCPClient(int clientID, String message) {
  if (clientID < 0 || clientID > 4) {  // 验证客户端ID有效性
    Serial.println("无效的客户端ID");
    return false;
  }
  
  if (message.length()==0) {  // 验证消息非空
    Serial.println("消息内容不能为空");
    return false;
  }
  
  // 1. 发送AT+CIPSEND指令，获取发送权限
  String sendCmd = "AT+CIPSEND=" + String(clientID) + "," + String(message.length());
  String response = sendATCommand(sendCmd, 2000);
  
  // 检查是否收到">"提示符
  if (response.indexOf(">") == -1) {
    Serial.println("未收到发送提示符，发送失败");
    return false;
  }
  
  // 2. 发送实际消息内容
  espSerial.println(message);
  
  // 3. 等待发送成功确认（可选，根据需要添加）
  delay(100);  // 短暂延时等待响应
  String sendResult = espSerial.readStringUntil('\n');
  if (sendResult.indexOf("SEND OK") == -1) {
    Serial.println("消息发送失败：" + sendResult);
    return false;
  }
  
  return true;
}

// --------------------------
// 发送AT命令并返回完整响应（字符串形式）
// 参数：
//   cmd：要发送的AT命令（如"AT+CIFSR"）
//   timeout：超时时间（毫秒）
// 返回值：
//   包含所有响应行的字符串（空字符串表示超时或无响应）
// --------------------------
String sendATCommand(String cmd, int timeout) {
  String response = "";  // 存储完整响应
  espSerial.flush();     // 清空串口缓冲区，避免残留数据

  // 发送AT命令（自动添加换行符，符合AT指令格式）
  Serial.println("发送命令："+cmd);
  espSerial.println(cmd);

  unsigned long startTime = millis();  // 记录开始时间

  // 循环读取所有响应，直到超时
  while (millis() - startTime < timeout) {
    if (espSerial.available()) {
      // 读取一行数据（以换行符结束）
      String line = espSerial.readStringUntil('\n');
      line.trim();  // 去除首尾空白字符（如回车符\r）

      // 拼接行到完整响应（每行用换行分隔）
      if (response.length() > 0) {
        response += "\n";  // 行之间添加换行符，保持格式清晰
      }
      response += line;

      // 调试输出当前行
      Serial.println("收到行："+line);
    }
  }

  return response;
}

void processCommand(String command) {
  command.trim(); // 移除首尾空白字符
  if (command.length() == 0) return;
  Serial.println("Processing command: " + command);
  
  // 处理电机控制命令
  if (command == "F") {
    Serial.println("Motor: FORWARD");
  } else if (command == "B") {
    Serial.println("Motor: BACKWARD");
  } else {
    Serial.println("Unknown command: " + command);
  }
  sendToTCPClient(clientID, "已经执行："+command);
}